#include "DoubleLinkedQueue.h"

DoubleLinkedQueue* init_queue() {
    DoubleLinkedQueue* queue =
        (DoubleLinkedQueue*)malloc(sizeof(DoubleLinkedQueue));
    queue->front = NULL;
    queue->rear = NULL;
    return queue;
}

Node* create_node(ElemType data) {
    Node* new_node = (Node*)malloc(sizeof(Node));
    new_node->data = data;
    new_node->next = NULL;
    new_node->prev = NULL;
    return new_node;
}

int is_empty(DoubleLinkedQueue* queue) { return queue->front == NULL; }

int size(DoubleLinkedQueue* queue) {
    int size = 0;
    for (Node* cur = queue->front; cur != NULL; cur = cur->next, size++);
    return size;
}

void enqueue_front(DoubleLinkedQueue* queue, ElemType data) {
    Node* new_node = create_node(data);
    if (is_empty(queue)) {
        queue->rear = new_node;
    } else {
        new_node->next = queue->front;
        queue->front->prev = new_node;
    }
    queue->front = new_node;
}

void enqueue_rear(DoubleLinkedQueue* queue, ElemType data) {
    Node* new_node = create_node(data);
    if (is_empty(queue)) {
        queue->front = new_node;
    } else {
        new_node->prev = queue->rear;
        queue->rear->next = new_node;
    }
    queue->rear = new_node;
}

ElemType dequeue_front(DoubleLinkedQueue* queue) {
    if (is_empty(queue)) {
        printf("dequeue_front: Queue is empty\n");
        return -1;
    }
    Node* temp = queue->front;
    ElemType data = temp->data;
    queue->front = queue->front->next;
    if (queue->front == NULL) {
        queue->rear = NULL;
    } else {
        queue->front->prev = NULL;
    }
    free(temp);
    return data;
}

ElemType dequeue_rear(DoubleLinkedQueue* queue) {
    if (is_empty(queue)) {
        printf("dequeue_rear: Queue is empty\n");
        return -1;
    }
    Node* temp = queue->rear;
    ElemType data = temp->data;
    queue->rear = queue->rear->prev;
    if (queue->rear == NULL) {
        queue->front = NULL;
    } else {
        queue->rear->next = NULL;
    }
    free(temp);
    return data;
}

ElemType front(DoubleLinkedQueue* queue) {
    if (is_empty(queue)) {
        printf("front: Queue is empty\n");
        return -1;
    }
    return queue->front->data;
}

ElemType rear(DoubleLinkedQueue* queue) {
    if (is_empty(queue)) {
        printf("rear: Queue is empty\n");
        return -1;
    }
    return queue->rear->data;
}

void dequque_all_front(DoubleLinkedQueue* queue) {
    printf("[FRONT <> ");
    while (!is_empty(queue)) {
        printf("%d <> ", dequeue_front(queue));
    }
    printf("REAR]\n");
}

void dequque_all_rear(DoubleLinkedQueue* queue) {
    printf("[REAR <> ");
    while (!is_empty(queue)) {
        printf("%d <> ", dequeue_rear(queue));
    }
    printf("FRONT]\n");
}

void clear_queue(DoubleLinkedQueue* queue) {
    while (!is_empty(queue)) {
        dequeue_front(queue);
    }
    free(queue);
    // 在调用clear_queue函数后，需要将队列的指针设置为NULL，以避免出现野指针。
}

// 标准队列不允许遍历

// void print_queue_front(DoubleLinkedQueue* queue) {
//     printf("[FRONT <> ");
//     Node* cur = queue->front;
//     while (cur != NULL) {
//         printf("%d <> ", cur->data);
//         cur = cur->next;
//     }
//     printf("<> TAIL]\n");
// }

// void print_queue_rear(DoubleLinkedQueue* queue) {
//     printf("[FRONT <> ");
//     Node* cur = queue->rear;
//     while (cur != NULL) {
//         printf("%d <> ", cur->data);
//         cur = cur->prev;
//     }
//     printf("<> TAIL]\n");
// }